// .........................................................................
// Title: excess_returns.do
//
// Computes excess bond returns in the US/TRACE sample
// .........................................................................

* --------------------------------------
* Excess returns to Treasury
* --------------------------------------

* what treasury returns to use: values in [crsp, strips, merged]
local treasury_type = "merged"

* return hedging: prep for merging in duration
use "$tmp/trace_enhanced_clean_returns_w", clear
gen date_m = mofd(dofw(date_w))
gen l_date_m = mofd(dofw(prev_date_w))
format %tm date_m l_date_m

* drop bonds for which we don't have duration
mmerge cusip using "$tmp/duration_merged_catalog", unmatched(m)
keep if _merge == 3

* merge in duration
mmerge cusip date_m using "$tmp/duration_merged", unmatched(m)
mmerge cusip l_date_m using "$tmp/duration_merged", unmatched(m) umatch(cusip date_m) uname(l_)
drop _merge
cap drop residual_maturity* maturity_filled 
drop duration_y
rename duration_m duration
rename l_duration_m l_duration

* drop if missing duration
drop if missing(duration) | missing(l_duration)

* cap duration at max treasury
if "`treasury_type'" == "crsp" {
    local max_treasury_duration = 200
}
else {
    local max_treasury_duration = 360
}
replace duration = `max_treasury_duration' if duration > `max_treasury_duration'
replace duration = 0 if duration < 0
replace l_duration = `max_treasury_duration' if l_duration > `max_treasury_duration'
replace l_duration = 0 if l_duration < 0

* merge in treasury returns and total return indices
if "`treasury_type'" == "strips" {
    mmerge duration date_w using "$tmp/treasury_returns_cm_w", unmatched(m)
    mmerge duration prev_date_w using "$tmp/treasury_returns_cm_w", unmatched(m) uname(prev_) umatch(duration date_w)    
}
if "`treasury_type'" == "crsp" {
    mmerge duration date_w using "$tmp/crsp_treasury_returns_w", unmatched(m)
    mmerge duration prev_date_w using "$tmp/crsp_treasury_returns_w", unmatched(m) uname(prev_) umatch(duration date_w)    
}
if "`treasury_type'" == "merged" {
    mmerge duration date_w using "$tmp/treasury_returns_merged_w", unmatched(m)
    mmerge duration prev_date_w using "$tmp/treasury_returns_merged_w", unmatched(m) uname(prev_) umatch(duration date_w)    
}
drop _merge

* check if hedging data is available
gen hedge_available = 0
replace hedge_available = 1 if ~missing(treasury_return)
replace hedge_available = 0 if weeks_gap > 1 & (missing(tri) | missing(prev_tri))

* drop if hedge not available
drop if hedge_available == 0

* construct the hedged returns
gen long_treasury_return = (1 + tri) / (1 + prev_tri) - 1
gen hedged_return = net_return - treasury_return
replace hedged_return = net_return - long_treasury_return if weeks_gap > 1
gen trading_gap = 1 if weeks_gap > 1
replace trading_gap = 0 if missing(trading_gap)
rename hedged_return hedged_return_raw
winsor2 hedged_return_raw, cuts(.1 99.9) trim
rename hedged_return_raw_t hedged_return    

* save it
keep cusip date_w net_return hedged_return trading_gap
gsort cusip date_w
save "$tmp/trace_enhanced_clean_returns_hedged_w", replace

* monthly version
use "$tmp/trace_enhanced_clean_returns_hedged_w", clear
gen date_m = mofd(dofw(date_w))
gen log_net_return = log(1 + net_return)
gen log_hedged_return = log(1 + hedged_return)
gcollapse (sum) log_*, by(cusip date_m)
gen net_return = exp(log_net_return) - 1
gen hedged_return = exp(log_hedged_return) - 1
drop log_*
save "$tmp/trace_enhanced_clean_returns_hedged_m", replace
